﻿using System.Collections.Generic;

namespace Framework.FluentDictionary
{
    /// <summary>
    /// 
    /// </summary>
    public class DictionaryFluent : BaseFluent<IDictionary<string, string>>, IDictionaryFluent
    {
        // *********************************************************************************
        // Properties
        // *********************************************************************************

        // *********************************************************************************
        // C'tor
        // *********************************************************************************

        public DictionaryFluent()
        {
            // Instance that this fluent provider is targeting
            Instance = new Dictionary<string, string>(FrameworkConstant.DEFAULT_COMPARER_IGNORECASE);
        }

        // *********************************************************************************
        // Overrides
        // *********************************************************************************

        public override string ToString()
        {
            return Instance.ToString();
        }

        // *********************************************************************************
        // Indent
        // *********************************************************************************

        /// <summary>
        /// Adds the specified key/value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>
        /// Fluent Reference
        /// </returns>
        public IDictionaryFluent Add(string key, string value)
        {
            Instance.Add(key, value);

            return this;
        }

        /// <summary>
        /// Adds the specified key/value.
        /// </summary>
        /// <param name="keyPrefix">The key prefix.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>
        /// Fluent Reference
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public IDictionaryFluent Add(string keyPrefix, string key, string value)
        {
            return Add(GetKey(keyPrefix, key), value);
        }

        public IDictionaryFluent Set(string keyPrefix, string key, string value)
        {
            return Set(GetKey(keyPrefix, key), value);
        }

        public IDictionaryFluent Set(string key, string value)
        {
            if (Instance.ContainsKey(key))
            {
                Instance[key] = value;
            }
            else
            {
                Instance.Add(key, value);
            }

            return this;
        }

        public IDictionaryFluent AddModel<TModel>(string namePrefix, TModel model) where TModel : class
        {
            var keyValues = DictionaryUtil.ReflectedPropertiesToKeyValueList(model);

            foreach (var kv in keyValues)
            {
                var key = GetKey(namePrefix, kv.Key);

                Set(key, kv.Value == null ? string.Empty : kv.Value.ToString());
            }

            return this;
        }

        public IDictionaryFluent AddDictionary(IEnumerable<KeyValuePair<string, string>> data)
        {
            return AddDictionary(string.Empty, data);
        }

        public IDictionaryFluent AddDictionary(string namePrefix, IEnumerable<KeyValuePair<string, string>> data)
        {
            foreach (var kv in data)
            {
                var key = GetKey(namePrefix, kv.Key);

                Set(key, kv.Value ?? string.Empty);
                //var expando = kv.Value as ExpandoObject;

                //if (expando != null)
                //{
                //    AddDictionary("{0}.{1}".FormatWith(name, kv.Key), expando);
                //}
                //else
                //{
                //    Settings.AddSetting(name, kv.Key,
                //                                   kv.Value == null ? string.Empty : kv.Value.ToString());
                //}
            }

            return this;
        }

        public IDictionaryFluent AddDictionary(IEnumerable<NameTextValueDo> data)
        {
            return AddDictionary(string.Empty, data);
        }

        public IDictionaryFluent AddDictionary(string namePrefix, IEnumerable<NameTextValueDo> data)
        {
            foreach (var kv in data)
            {
                var key = GetKey(namePrefix, kv.Name);

                Set(key, kv.Value ?? string.Empty);
            }

            return this;
        }

        IDictionary<string, string> IDictionaryFluent.AsDictionary()
        {
            return Instance;
        }

        // *********************************************************************************
        // Private Helpers 
        // *********************************************************************************
        private static string GetKey(string keyPrefix, string key)
        {
            return Is.EmptyString(keyPrefix) ? key : "{0}.{1}".FormatWith(keyPrefix, key);
        }
    }
}